home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / progutil / stdwin.zoo / atari / trees.c < prev    next >
C/C++ Source or Header  |  1990-03-30  |  4KB  |  219 lines

  1. #include <stdio.h>
  2. #include <assert.h>
  3.  
  4. #include <aesbind.h>
  5. #include <vdibind.h>
  6. #ifdef __GNUC__
  7. #include <gemfast.h>
  8. #else
  9. #include <obdefs.h>
  10. #include <gemdefs.h>
  11. #endif
  12.  
  13. #include "l_defs.h"
  14.  
  15. #include "window.h"
  16. #include "trees.h"
  17. #include "atari_proto.h"
  18. #undef P
  19.  
  20. #define bool int
  21. #define TRUE 1
  22. #define FALSE 0
  23.  
  24. #define NEXT(i) t->obj[i].ob_next
  25. #define HEAD(i) t->obj[i].ob_head
  26. #define TAIL(i) t->obj[i].ob_tail
  27.  
  28. /* Move the focus to the root node of the tree.
  29.    Return TRUE if the tree isn't empty. */
  30.  
  31. bool
  32. tr_root(t)
  33.     TREE *t;
  34. {
  35.     t->focus= 0;
  36.     return t->nobjs > 0;
  37. }
  38.  
  39. /* Move the focus to its parent.
  40.    Return TRUE if not already at the root. */
  41.  
  42. bool
  43. tr_parent(t)
  44.     TREE *t;
  45. {
  46.     int old;
  47.     if (t->focus == 0)
  48.         return FALSE;
  49.     do {
  50.         old= t->focus;
  51.         t->focus= NEXT(t->focus);
  52.         assert(t->focus >= 0 && t->focus < t->nobjs);
  53.     } while (TAIL(t->focus) != old);
  54.     return TRUE;
  55. }
  56.  
  57. /* Move the focus to its sibling.
  58.    Return TRUE if not already at the last sibling. */
  59.  
  60. bool
  61. tr_sibling(t)
  62.     TREE *t;
  63. {
  64.     int new;
  65.     if (t->nobjs <= 0)
  66.         return FALSE;
  67.     new= NEXT(t->focus);
  68.     if (TAIL(new) == t->focus)
  69.         return FALSE;
  70.     t->focus= new;
  71.     return TRUE;
  72. }
  73.  
  74. /* Move the focus to the first child.
  75.    Return FALSE if no children. */
  76.  
  77. bool
  78. tr_child(t)
  79.     TREE *t;
  80. {
  81.     int new= HEAD(t->focus);
  82.     if (new < 0)
  83.         return FALSE;
  84.     t->focus= new;
  85.     return TRUE;
  86. }
  87.  
  88. /* Return the number of children of the current node.
  89.    Return -1 if the tree is empty.
  90.    Warning: this may loop infinitely if the tree is malformed. */
  91.  
  92. int
  93. tr_nchildren(t)
  94.     TREE *t;
  95. {
  96.     int i= t->focus;
  97.     int hd;
  98.     int n= 0;
  99.     
  100.     if (i >= t->nobjs)
  101.         return -1;
  102.     if ((hd= HEAD(i)) < 0)
  103.         return 0;
  104.     while (hd != i)
  105.         ++n, hd= NEXT(hd);
  106.     return n;
  107. }
  108.  
  109. /* Add a new node to the tree.
  110.    If 'as_child' is TRUE, it is a new child of the current node;
  111.    otherwise, it is its sibling. */
  112.  
  113. OBJECT *
  114. tr_add(t, as_child, type, flags, state, spec, x, y, width, height)
  115.     TREE *t;
  116.     int as_child;
  117.     int type, flags, state;
  118.     long spec;
  119.     int x, y, width, height;
  120. {
  121.     int new;
  122.     OBJECT *o;
  123.     L_EXTEND(t->nobjs, t->obj, OBJECT, 1);
  124.     if (t->obj == NULL)
  125.         return NULL;
  126.     new= t->nobjs - 1;
  127.     if (new == 0) { /* Creating the root */
  128.         NEXT(new)= -1;
  129.     }
  130.     else if (as_child) { /* Add as first child of focus */
  131.         assert(HEAD(t->focus) < 0); /* Must be first */
  132.         HEAD(t->focus)= TAIL(t->focus)= new;
  133.         NEXT(new)= t->focus;
  134.     }
  135.     else { /* Add as sibling of focus */
  136.         assert(TAIL(NEXT(t->focus)) == t->focus); /* Must be last */
  137.         NEXT(new)= NEXT(t->focus);
  138.         NEXT(t->focus)= new;
  139.         TAIL(NEXT(new))= new;
  140.     }
  141.     HEAD(new)= TAIL(new)= -1;
  142.     t->focus= new;
  143.     o= &t->obj[new];
  144.     o->ob_type= type;
  145.     o->ob_flags= flags;
  146.     o->ob_state= state;
  147.     o->ob_spec= spec;
  148.     o->ob_x= x;
  149.     o->ob_y= y;
  150.     o->ob_width= width;
  151.     o->ob_height= height;
  152.     return o;
  153. }
  154.  
  155. /* Print a dump of a tree. */
  156.  
  157. void
  158. tr_dump(t)
  159.     TREE *t;
  160. {
  161.     FILE    *fp ;
  162.     int i= 0;
  163.     int level= 0;
  164.  
  165.     if ((fp = fopen ("tree.dmp", "w")) == NULL)
  166.         wdebug ("Cannot open dump file") ;
  167.  
  168.     if (t->nobjs <= 0) {
  169.         fprintf(fp, "Empty tree.\n");
  170.         return;
  171.     }
  172.     do {
  173.         int k;
  174.  
  175.         fprintf(fp, "%d.", i);
  176.  
  177.         for (k= 0; k < level; ++k)
  178.             fprintf(fp, "    ");
  179.  
  180.         fprintf (fp, "  %d, %d, %d, %d", t->obj[i].ob_x, t->obj[i].ob_y,
  181.                     t->obj[i].ob_width, t->obj[i].ob_height) ;
  182.         if (t->obj[i].ob_type == G_TITLE || t->obj[i].ob_type == G_STRING)
  183.             fprintf (fp, "   %s\n", t->obj[i].ob_spec) ;
  184.         else
  185.             fprintf (fp, "\n") ;
  186.         if (HEAD(i) >= 0) {
  187.             ++level;
  188.             i= HEAD(i);
  189.         }
  190.         else {
  191.             while (NEXT(i) >= 0 && TAIL(NEXT(i)) == i) {
  192.                 --level;
  193.                 i= NEXT(i);
  194.             }
  195.             i= NEXT(i);
  196.         }
  197.     } while (i >= 0);
  198.     fclose (fp) ;
  199. }
  200.  
  201. OBJECT *
  202. tr_node(t)
  203.     TREE *t;
  204. {
  205.     if (t->nobjs <= 0)
  206.         return NULL;
  207.     return &t->obj[t->focus];
  208. }
  209.  
  210. OBJECT *
  211. tr_tree(t)
  212.     TREE *t;
  213. {
  214.     if (t->nobjs <= 0)
  215.         return NULL;
  216.     t->obj[t->nobjs - 1].ob_flags |= LASTOB;
  217.     return t->obj;
  218. }
  219.